﻿using System.Diagnostics;

using SimpleJson;
using System.Collections.Generic;
using System;

namespace ABA
{
    public class Json : Singleton<Json>
    {
        public Json()
        {
        }

        public T Deserialize<T>(string json)
        {
            return SimpleJson.SimpleJson.DeserializeObject<T>(json);
        }

        public JsonObject Deserialize(string json)
        {
            return (JsonObject)SimpleJson.SimpleJson.DeserializeObject(json);
        }

        public string Serialize(JsonObject jsonData)
        {
            return SimpleJson.SimpleJson.SerializeObject(jsonData);
        }

        public string Serialize(object jsonData)
        {
            return SimpleJson.SimpleJson.SerializeObject(jsonData);
        }

        // JsonObject，JsonArray 继承 object
        // JsonObject param["a"] = 8   JsonManager.instance.OneLevelForEach(param, (key, v)=>{
        //     key // a
        //     int vv if(v.GetType() == typeof(int)) vv = (int)v  // 8
        // })
        public void OneLevelForEach(JsonObject jd, Action<string, object> cb){
            ICollection<string> keys = jd.Keys;
            foreach (string key in keys)
            {
                object v = (object)jd[key];
                cb(key, v);
            }
        }
        //合并两个对象，override,是否覆盖
        public JsonObject extend(JsonObject a, JsonObject b, bool isOverride = true){
            ICollection<string> b_keys = b.Keys;
            foreach (string bkey in b_keys)
            {
                object bv = (object)b[bkey];
                if(a.ContainsKey(bkey) == false || isOverride == true){
                    a[bkey] = bv;
                }
            }
            return a;
        }

        public T SetJOToMsgObj<T>(T a, JsonObject b){
            var oType = typeof(T);
            ICollection<string> b_keys = b.Keys;
            foreach (string bkey in b_keys)
            {
                object bv = (object)b[bkey];
                var oPro = oType.GetProperty(bkey);
                if(oPro != null){
                    if(oPro.PropertyType.ToString() == typeof(double).ToString()){
                        double vv = (double)ToDouble(bv);
                        oPro.SetValue(a, vv, null);
                    }
                    else if(oPro.PropertyType.ToString() == typeof(float).ToString()){
                        float vv = (float)ToFloat(bv);
                        oPro.SetValue(a, vv, null);
                    }
                    else if(oPro.PropertyType.ToString() == typeof(int).ToString() || oPro.PropertyType.ToString() == typeof(long).ToString()){
                        int vv = (int)ToInt(bv);
                        oPro.SetValue(a, vv, null);
                    }
                    else{
                        oPro.SetValue(a, bv, null);
                    }

                    // if(IsInt(bv)){
                    //     int vv = (int)ToInt(bv);
                    //     oPro.SetValue(a, vv, null);
                    // }
                    // else{
                    //     oPro.SetValue(a, bv, null);
                    // }
                }
                else{
                    var oField = oType.GetField(bkey);
                    if(IsInt(bv)){
                        int vv = (int)ToInt(bv);
                       //UnityEngine.Debug.Log(" ~~ " + a+" "+bkey+ " "+bv);
                        oField.SetValue(a, vv);
                    }
                    else{
                        // if(IsIntArr(bv)){
                        //     var bbv = bv as JsonArray;
                        //     object[] xxx = bbv.ToArray();
                        //     int[] bbvv = new int[xxx.Length];
                        //     for (int i = 0; i < xxx.Length; i++)
                        //     {
                        //         bbvv[i] = (int)xxx[i];
                        //     }
                        //     oField.SetValue(a, bbvv);
                        // }
                        // else{
                           // UnityEngine.Debug.Log(" -- " + a+" "+bkey+ " "+bv);
                            oField.SetValue(a, bv);                            
                        // }
                    }
                }
            }

            return a;
        }

        public bool IsInt(object o){
            var s = o.GetType().ToString();
            if(s == typeof(long).ToString() || s == typeof(int).ToString()){
                return true;
            }
            return false;
        }

        public bool IsIntArr(object o){
            var s = o.GetType().ToString();
            if(s == typeof(long[]).ToString() || s == typeof(int[]).ToString()){
                return true;
            }
            return false;
        }

        public bool IsFloat(object o){
            var s = o.GetType().ToString();
            if(s == typeof(double).ToString() || s == typeof(float).ToString()){
                return true;
            }
            return false;
        }
        public bool IsString(object o){
            var s = o.GetType().ToString();
            if(s == typeof(string).ToString()){
                return true;
            }
            return false;
        }

        public int ToInt(object o){
            return Convert.ToInt32(o);
        }
        public long ToLong(object o){
            return Convert.ToInt64(o);
        }

        public double ToDouble(object o){
            return Convert.ToDouble(o);            
        }

        public double ToFloat(object o){
            return Convert.ToSingle(o);            
        }
    }
}